/*
 * @Author: 9ilk 3535851673@qq.com
 * @Date: 2025-03-20 20:47:06
 * @LastEditors: 9ilk 3535851673@qq.com
 * @LastEditTime: 2025-03-20 21:29:33
 * @FilePath: /zhuang/ReadWriteMutex/ReadWrite.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>
#include <ctime>
using namespace std;

// 共享资源
int shared_data = 0;

// 读写锁
pthread_rwlock_t rwlock;

// 读线程的调用函数
void *Reader(void *arg)
{
    int number = *(int *)arg;
    // sleep(1);
    while (true)
    {
        pthread_rwlock_rdlock(&rwlock); // 读者身份申请锁
        cout << "读者-" << number << " 正在读取数据,数据是：" << shared_data << endl;
        sleep(2);
        pthread_rwlock_unlock(&rwlock);
    }
    delete (int *)arg;
    return nullptr;
}

// 写线程的调用函数
void *Writer(void *arg)
{
    int number = *(int *)arg;
    while (true)
    {
        pthread_rwlock_wrlock(&rwlock); // 以写者身份申请锁
        shared_data = rand() % 100;     // 修改共享数据
        cout << "写者-" << number << " 正在写入数据,新数据是：" << shared_data << endl;
        sleep(2);
        pthread_rwlock_unlock(&rwlock); // 释放锁
    }
    delete (int *)arg;
    return nullptr;
}

int main()
{
    srand(time(nullptr)^getpid());
    pthread_rwlock_init(&rwlock, nullptr); // 初始化读写锁
    //初始化读写锁属性
    pthread_rwlockattr_t attr;
    pthread_rwlockattr_init(&attr);

    //设置写者优先
    pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
    //PTHREAD_RWLOCK_PREFER_WRITER_NP有bug
    //使用该属性初始化读写锁
    pthread_rwlock_init(&rwlock, &attr);
    pthread_rwlockattr_destroy(&attr);

    // 分配数量 --- pthread库
    const int read_num = 2;
    const int write_num = 2;
    const int total = read_num + write_num;
    pthread_t threads[total]; // 假设读者和写者数量相等

    // 创建读者线程
    for (int i = 0; i < read_num; i++)
    {
        int *id = new int(i);
        ::pthread_create(&threads[i], NULL, Reader, id);
    }

    // 创建写者线程
    for (int i = read_num; i < total; i++)
    {
        int *id = new int(i - read_num);
        ::pthread_create(&threads[i], NULL, Writer, id);
    }
    //等待所有线程工作完成
    for(int i = 0 ; i < total ; i++)
    {
         ::pthread_join(threads[i],nullptr);
    }
    //销毁读写锁
    pthread_rwlock_destroy(&rwlock);
    return 0;
}